home *** CD-ROM | disk | FTP | other *** search
- /** 3DGPL *************************************************\
- * () *
- * 3-D volume and Z clipping. *
- * *
- * Defines: *
- * C_volume_clipping Out-of view volume elements; *
- * *
- * C_line_z_clipping Clipping a line; *
- * C_polygon_z_clipping View plane cliping. *
- * *
- * (6/1995) By Sergei Savchenko. (savs@cs.mcgill.ca). *
- * Copyright (c) 1995 Sergei Savchenko. *
- * THIS SOURCE CODE CAN'T BE USED FOR COMERCIAL PURPOSES *
- * WITHOUT AUTHORISATION *
- \**********************************************************/
-
- #include <limits.h> /* INT_MAX & INT_MIN */
-
- #ifdef __MWERKS__
- #include "hardware.h" /* HW_copy_int stuff */
- #include "clipper.h" /* clipping constants */
- #else
- #include "../hardware/hardware.h" /* HW_copy_int stuff */
- #include "../clipper/clipper.h" /* clipping constants */
- #endif
-
- int C_3D_clipping; /* type of performed clipping */
-
- /**********************************************************\
- * Hole element volume clipping, *
- * *
- * RETURNS: 0 when array of passed vertices is for sure *
- * -------- outside the view volume; *
- * -1 when further clipping is required; *
- * 1 when element has a fair chanse to be *
- * inside the view volume, and should be *
- * clipped by 2-D clipping when rendering *
- * onto the screen. *
- * *
- * | z *
- * \ | / View volume is a piramid *
- * \ | / with 90 degree angle. *
- * \ | / *
- * -x>z \ | / x>z *
- * \|/ *
- * --------+--------- x *
- * z<C_Z_CLIPPING_MIN *
- * *
- * ADDITIONAL FUNCTIONS: 1) extraction of tuples & *
- * --------------------- FORMAT change *
- * source: n,a1,...,aN where N=dimension-3 *
- * destanation: x,y,z,a1,...,aN (x,y,z extracted from *
- * int *vertex array starting from index n) *
- \**********************************************************/
-
- int C_volume_clipping(register int *from,register int *to,
- int *vertex,int dimension,int length
- )
- {
- register int i;
- int xmin,ymin,zmin,xmax,ymax,zmax;
-
- dimension-=3; /* but X,Y,Z */
-
- ymin=xmin=zmin=INT_MAX;
- ymax=xmax=zmax=INT_MIN; /* initializing searching */
-
- for(i=0;i<length;i++)
- {
- HW_copy_int(&vertex[*from++],to,3); /* copying actual tuples */
-
- if(*to>xmax) xmax=*to; /* determining polygon extend */
- if(*to<xmin) xmin=*to;
- to++;
- if(*to>ymax) ymax=*to;
- if(*to<ymin) ymin=*to;
- to++;
- if(*to>zmax) zmax=*to;
- if(*to<zmin) zmin=*to; /* by searching max/min */
- to++;
-
- HW_copy_int(from,to,dimension); /* rest (for shading etc)*/
- to+=dimension;
- from+=dimension;
- }
-
- if((zmax<xmin)||(zmax<ymin)||(zmax<-xmax)||
- (zmax<-ymax)||(zmax<=C_Z_CLIPPING_MIN))
- return(0); /* outside */
- else
- if(zmin<C_Z_CLIPPING_MIN) return(-1); /* partly behind clipping plane */
- else return(1);
- }
-
- /**********************************************************\
- * Line clipping using binary search technique. *
- * *
- * RETURNS: 0 element is outside the view volume; *
- * ------- 1 element is clipped to the view volume. *
- * *
- * SETS: C_3D_clipping to 1 if first vertex was clipped; *
- * ----- 0 otherwise. *
- \**********************************************************/
-
- int C_line_z_clipping(int **vertex1,int **vertex2,int dimension)
- {
- register int i;
- register int whereto;
- register int *l,*r,*m,*t; /* left right and midle and tmp */
- static int c_store0[C_MAX_DIMENSIONS]; /* static stores for clipped vxes */
- static int c_store1[C_MAX_DIMENSIONS];
- static int c_store2[C_MAX_DIMENSIONS];
- int **vmn,**vmx; /* so that *vmn[3] < *vmx[3] */
- int swap; /* were coordinates swaped? */
-
- C_3D_clipping=0; /* default no clipping yet */
-
- if((*vertex1)[2]<(*vertex2)[2]) /* only Z counts 0=X,1=Y,2=Z,... */
- { swap=0; vmn=vertex1; vmx=vertex2; } /* so that *vmn[2] < *vmx[2] */
- else
- { swap=1; vmn=vertex2; vmx=vertex1; }
-
- if((*vmx)[2]<C_Z_CLIPPING_MIN) return(0);
- else
- {
- if((*vmn)[2]<=C_Z_CLIPPING_MIN) /* clipping */
- {
- HW_copy_int(*vmn,l=c_store0,dimension); /* copying old vertices */
- HW_copy_int(*vmx,m=c_store1,dimension);
- r=c_store2;
-
- whereto=0;
- while(m[2]!=C_Z_CLIPPING_MIN)
- {
- if(whereto==1) { t=l; l=m; m=t; }
- else { t=r; r=m; m=t; }
- for(i=0;i<dimension;i++) m[i]=(l[i]+r[i])>>1;
- whereto=m[2]<C_Z_CLIPPING_MIN;
- }
- *vmn=m; /* that is why m[] is static */
- C_3D_clipping=swap^1;
- }
- return(1); /* partialy or not clipped */
- }
- }
-
- /***********************************************************\
- * Creating a z-clipped polygon. *
- * *
- * RETURNS: number of elements in the clipped polygon. *
- * ------- (0 when compleately behind view plane) *
- * *
- * | 1-2-3-4-5-6-1 -> 2-2'-5'-6-1-2 *
- * |5' *
- * 5*-*-----*6 If first dot in the line is being *
- * / | \ clipped both points are copyed, *
- * 4* | *1 If no clipping or second point is *
- * \ | / clipped then only second point is *
- * 3*-*-----*2 copyed. If both points are *
- * |2' clipped well, neither is copyed. *
- \***********************************************************/
-
- int C_polygon_z_clipping(register int *from,register int *to,
- int dimension,int length
- )
- {
- register int i;
- int *v1,*v2,new_lng=0;
- int *first_vrtx=to; /* begining of the source */
-
- for(i=0;i<length;i++) /* for all edges */
- {
- v1=from; from+=dimension; v2=from; /* taking two vertices */
-
- if(C_line_z_clipping(&v1,&v2,dimension)) /* clipping */
- {
- if(C_3D_clipping) /* depends which one was clipped */
- {
- HW_copy_int(v1,to,dimension); to+=dimension;
- HW_copy_int(v2,to,dimension); to+=dimension;
- new_lng+=2; /* first point clipped */
- }
- else
- {
- HW_copy_int(v2,to,dimension); to+=dimension;
- new_lng++; /* second point clipped */
- }
- }
- }
- HW_copy_int(first_vrtx,to,dimension); /* looping the polygon vertices */
-
- return(new_lng);
- }
-
- /**********************************************************/
-